﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace SMS_Server
{
    class Service_Controller
    {
        Thread th;
        TcpListener listener;

        public void StartServer()
        {
            th = new Thread(StartListening);
            th.Start();
        }

        public void Close()
        {
            if (th == null) return;
            try
            {
                listener.Stop();
                th.Abort();
            }
            catch { }
        }

        private void StartListening()
        {
            try
            {
                System.Net.IPAddress ip = Global.GetDefaultIP();
                 listener= new TcpListener(ip, 2000);//port 2000 is management port
                try
                {
                    listener.Start();
                    System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
                    el.Log = "Application";
                    el.MachineName = ".";
                    el.Source = "SMS Server";
                    el.WriteEntry("Listening to " + ip.ToString() + " on port 2000", System.Diagnostics.EventLogEntryType.Information);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
                    el.Log = "Application";
                    el.MachineName = ".";
                    el.Source = "SMS Server";
                    el.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error);
                    return;
                }
                while (!Global.ShuttingDown)
                {
                    try
                    {
                        TcpClient tcp = listener.AcceptTcpClient();
                        Thread th = new Thread(new ParameterizedThreadStart(CommandExecutive));
                        th.Start(tcp);
                    }
                    catch
                    {
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
                el.Log = "Application";
                el.MachineName = ".";
                el.Source = "SMS Server";
                el.WriteEntry("Error in service controller: "+ex.Message, System.Diagnostics.EventLogEntryType.Error);
            }
        }

        private void CommandExecutive(object TCP)
        {
            TcpClient tcp = (TcpClient)TCP;
            NetworkStream ns = tcp.GetStream();
            StreamReader sr = new StreamReader(ns);
            StreamWriter sw = new StreamWriter(ns);

            while (!Global.ShuttingDown)
            {

                try
                {
                    string Command = sr.ReadLine();
                    switch (Command)
                    {
                        case "SQ"://Signal quality
                            sw.WriteLine(GetSignalStrength().ToString());
                            break;
                        case "NSQ"://Number of messages in sending que
                            sw.WriteLine(MessagesInSendingQue().ToString());
                            break;
                        case "NPQ"://Number of messages in processing que
                            sw.WriteLine(MessagesInProcessingQue().ToString());
                            break;
                        case "CD"://get current device
                            sw.WriteLine(CurrentDevice());
                            break;
                        case "DL"://get device list
                            sw.WriteLine(GetDeviceList());
                            break;
                        case "SMS"://send sms
                            string phone = sr.ReadLine();
                            string message = sr.ReadLine();
                            sw.WriteLine(SendMessage(phone, message));
                            break;
                        case "GF"://get device list
                            sw.WriteLine(getFunctions());
                            break;
                        default://invalid command
                            sw.WriteLine("Invalid command");
                            break;
                    }
                    sw.Flush();
                }
                catch
                {
                    try
                    {
                        sw.Dispose();
                        sr.Dispose();
                    }
                    catch { }
                    break;
                }

                Thread.Sleep(100);
            }
        }

        private string getFunctions()
        {
            string s = "";
            foreach (Function f in Global.Tasks.Values)
            {
                if (s != "") s += "|";
                s += f.FunctionName;
                foreach (Incoming_Action ia in f.Actions)
                {
                    s += ":";
                    s += ia.GetType().ToString();
                }
            }
                return s;
        }

        private string SendMessage(string PhoneNumbers, string Message)
        {
            Message = Message.Replace("`", Encoding.ASCII.GetString(new byte[] { 13 }));
            string[] Numbers = PhoneNumbers.Replace(" ", "").Split(';');
            string error = "";
            if (Message.Length >= 720) return "Message is too large and can't be sent";
            for (int i = 0; i < Numbers.Length; i++)
            {
                string s = Numbers[i];
                if (s.Substring(0, 2) == "00") s = "+" + s.Substring(2);
                if (s[0] != '+') { if (error != "")error += " "; error += s + " is not a valid number."; continue; }
                Global.SendSMS(s, Message);
            }
            if (!Global.DeviceManager.SystemConfigured) error = "There is an issue with the GSM device"; else error = "SUCCESS";
            return error;
        }

        private string GetDeviceList()
        {
            string result = "";
            Global.Refresh_DeviceList();
            for (int i = 0; i < Global.Devices.Count; i++)
            {
                if (result != "") result += "|";
                result += Global.Devices[i].DeviceName + "," + Global.Devices[i].IMEINumber + "," + Global.Devices[i].PhoneNumber + "," + Global.Devices[i].PortName;
            }
            return result;
        }

        private string CurrentDevice()
        {
            try
            {
                if (Global.DeviceManager.SystemConfigured == false) return "";
                return Global.DeviceManager.Manufacturer + " " + Global.DeviceManager.Model + "," + Global.DeviceManager.IMEI + "," + Global.DeviceManager.MyNumber + "," + Global.DeviceManager.comPort.PortName;
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
                el.Log = "Application";
                el.MachineName = ".";
                el.Source = "SMS Server";
                el.WriteEntry("Geting Device Data: " + ex.Message, System.Diagnostics.EventLogEntryType.Error);
                return "";
            }
        }

        private int MessagesInSendingQue()
        {
            return Global.Outbox.Count;
        }

        private int MessagesInProcessingQue()
        {
            return Global.Inbox.Count;
        }

        private int GetSignalStrength()
        {
            try
            {
                if (Global.DeviceManager.SystemConfigured == false) return 0;
                return Global.DeviceManager.SignalStrength;
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
                el.Log = "Application";
                el.MachineName = ".";
                el.Source = "SMS Server";
                el.WriteEntry("Geting Signal Strength: " + ex.Message, System.Diagnostics.EventLogEntryType.Error);
                return 0;
            }
        }
    
    }
}
